/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package matematicadiscretaxml;

import arbol_prueba.BTree;
import arbol_prueba.BTreeException;
import java.util.ArrayList;
import java.util.Stack;

/**
 *
 * @author diego
 */
public class CreacionTablas {
 
    private ArrayList lista_lexemas = new ArrayList();

    ObjetoQuery tabla_obj_query[][] = new ObjetoQuery[0][0];//TABLA QUE RESULTA DEL PRODUCTO CARTESIANO
    ObjetoQuery vector_select[] = new ObjetoQuery[0];//VECTOR DE CAMPOS DEL SELECT
    ArrayList lista_errores_creacion_tablas = new ArrayList();//GUARDA LOS ERRORES
    ArrayList<DefinicionTabla> lista_atributos_tabla_crear = new ArrayList();
    DefinicionTabla obj_def_tabla = new DefinicionTabla();
    String nombre_tabla = "";
    int contador_campos = 0;

    OperacionesArchivoXML obj_opera_en_xml = new OperacionesArchivoXML();


    Stack pila_pal_reserv = new Stack();
    Stack pila_identifica = new Stack();
    Stack pila_simbolos = new Stack();

    public CreacionTablas(){}

    public CreacionTablas(ArrayList _lista_lexemas)
    {
        lista_lexemas = _lista_lexemas;
    }

    public void generarArbolSintacticoCreacionTablas()
    {
        Create obj_create = new Create(lista_lexemas);
        Table obj_table = new Table(lista_lexemas);
        CreacionTablasCuerpo obj_create_cuerpo = new CreacionTablasCuerpo(lista_lexemas);
        BTree sub_arbol_create = null;
        BTree sub_arbol_table = null;
        BTree sub_arbol_create_cuerpo = null;

        obj_create.ingresarPilas();
        sub_arbol_create = obj_create.generarSubArbolCreate(new BTree("nulo"));
        lista_errores_creacion_tablas.addAll(obj_create.getlista_errores_create());

        if(lista_errores_creacion_tablas.isEmpty())
        {
System.out.println("**************************************************************");

            sub_arbol_create.imprimePostOrden();

System.out.println("**************************************************************");

            obj_table.ingresarPilas();
            sub_arbol_table = obj_table.generarSubArbolTable(new BTree("nulo"));
            lista_errores_creacion_tablas.addAll(obj_table.getlista_errores_table());

            if(lista_errores_creacion_tablas.isEmpty())
            {
                sub_arbol_table.imprimePostOrden();
System.out.println("**************************************************************");

                obj_create_cuerpo.ingresarPilas();
                sub_arbol_create_cuerpo = obj_create_cuerpo.generarSubArbolCuerpoCreate(new BTree("nulo"));
                lista_errores_creacion_tablas.addAll(obj_create_cuerpo.getlista_errores_create_cuerpo());

                if(lista_errores_creacion_tablas.isEmpty())
                {
                    sub_arbol_create_cuerpo.imprimePostOrden();
System.out.println("****************************** TODO BIEN ********************************");
                    ejecutarCreacionTabla(sub_arbol_create,sub_arbol_table,sub_arbol_create_cuerpo);
                    if(lista_errores_creacion_tablas.isEmpty())
                    {

                    }
                }
            }
        }
    }

    public void ejecutarCreacionTabla(BTree sub_arbol_create, BTree sub_arbol_table, BTree sub_arbol_create_cuerpo)
    {

        recorrerSubArbolCreate(sub_arbol_create);
        if(lista_errores_creacion_tablas.isEmpty())
        {
            recorrerSubArbolTable(sub_arbol_table);
            if(lista_errores_creacion_tablas.isEmpty())
            {
                
                recorrerSubArbolCuerpoCreate(sub_arbol_create_cuerpo);
                if(!lista_errores_creacion_tablas.isEmpty())
                {
                    tabla_obj_query = new ObjetoQuery[0][0];
                }
                else
                {
                    System.out.println("**HASTA AQUI VA BIEN**");
                    
                    imprimirMatriz(tabla_obj_query);
                    if(obj_def_tabla.getForanea().equals(""))
                    {
                        obj_def_tabla.setForanea("no");
                        obj_def_tabla.setTabla_referencia("nulo");
                    }
                    if(obj_def_tabla.getPrimaria().equals(""))
                    {
                        obj_def_tabla.setPrimaria("no");
                    }
                    lista_atributos_tabla_crear.add(obj_def_tabla);
                    for(int i = 0; i<lista_atributos_tabla_crear.size(); i++)
                    {
                        System.out.print(lista_atributos_tabla_crear.get(i).getNombre_tabla()+" | "+
                                lista_atributos_tabla_crear.get(i).getNombre()+" | "+
                                lista_atributos_tabla_crear.get(i).getTipo_dato()+" | "+
                                lista_atributos_tabla_crear.get(i).getPrimaria()+" | "+
                                lista_atributos_tabla_crear.get(i).getForanea()+" | "+
                                lista_atributos_tabla_crear.get(i).getTabla_referencia()+" | "   );
            
                        
                        System.out.println("");
                    }
                    XML obj_xml = new XML("hola");
                    obj_xml.crearNuevoArchivoXML(lista_atributos_tabla_crear);
                    obj_xml.setCadena_ruta("archivos_usados/analisis_lexico/diccionario/tablas.xml");
                    ArrayList<ObjetoQuery> arreglo_aux = new ArrayList();
                    arreglo_aux.add(new ObjetoQuery("tabla", "nombre", nombre_tabla));
                    arreglo_aux.add(new ObjetoQuery("tabla", "nombre", "nulo"));
                    obj_xml.ingresarRegistroXMLDiccionarioTablas(arreglo_aux);
                }
            }
            else
            {
                tabla_obj_query = new ObjetoQuery[0][0];
            }
        }
        else
        {
            tabla_obj_query = new ObjetoQuery[0][0];
        }
    }

    public void recorrerSubArbolCuerpoCreate(BTree nodo)
    {
        if( nodo.getIzquierda()!= null )
        {
            recorrerSubArbolCuerpoCreate(nodo.getIzquierda());
        }
        if(nodo.getDerecha() != null)
        {
            recorrerSubArbolCuerpoCreate(nodo.getDerecha());
        }
        
        if( ((Lexema)nodo.getElement()).getTipo_lexema() ==  1)
        {
            if(  ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("varchar")
                 || ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("double")
              )
            {
                if ( ((Lexema)nodo.getDerecha().getElement()).getLexema() == null
                   &&  ((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 4     )
                {
                    contador_campos ++;
                    
                    if(contador_campos == 1)
                    {
                        obj_def_tabla.setNombre_tabla(nombre_tabla);
                        obj_def_tabla.setTipo_dato(((Lexema)nodo.getElement()).getLexema().toLowerCase());
                        obj_def_tabla.setNombre(((Lexema)nodo.getIzquierda().getElement()).getLexema());
                    }
                    else
                    {
                        if(obj_def_tabla.getForanea().equals(""))
                        {
                            obj_def_tabla.setForanea("no");
                            obj_def_tabla.setTabla_referencia("nulo");
                        }
                        if(obj_def_tabla.getPrimaria().equals(""))
                        {
                            obj_def_tabla.setPrimaria("no");
                        }
                        lista_atributos_tabla_crear.add(obj_def_tabla);
                        obj_def_tabla = new DefinicionTabla();
                        obj_def_tabla.setNombre_tabla(nombre_tabla);
                        obj_def_tabla.setTipo_dato(((Lexema)nodo.getElement()).getLexema().toLowerCase());
                        obj_def_tabla.setNombre(((Lexema)nodo.getIzquierda().getElement()).getLexema());
                        
                    }
                    
                    contador_campos++;
//                    obj_def_tabla.setTipo_dato(((Lexema)nodo.getElement()).getLexema().toLowerCase());
//                    obj_def_tabla.setNombre(((Lexema)nodo.getIzquierda().getElement()).getLexema());
//                    
//                    if(contador_campos == 0)
//                    {
//                        lista_atributos_tabla_crear.add(obj_def_tabla);
//                        obj_def_tabla.setNombre_tabla(nombre_tabla);
//                        obj_def_tabla.setTipo_dato(((Lexema)nodo.getElement()).getLexema().toLowerCase());
//                        obj_def_tabla.setNombre(((Lexema)nodo.getIzquierda().getElement()).getLexema());
//                        
//                        contador_campos++;
//                    }
//                    else
//                    {
//                        if(obj_def_tabla.getForanea().equals(""))
//                        {
//                            obj_def_tabla.setForanea("no");
//                            obj_def_tabla.setTabla_referencia("nulo");
//                        }
//                        if(obj_def_tabla.getPrimaria().equals(""))
//                        {
//                            obj_def_tabla.setPrimaria("no");
//                        }
//                        lista_atributos_tabla_crear.add(obj_def_tabla);
//    
//                        obj_def_tabla = new DefinicionTabla();
//                        obj_def_tabla.setNombre_tabla(nombre_tabla);
//                        obj_def_tabla.setTipo_dato(((Lexema)nodo.getElement()).getLexema().toLowerCase());
//                        obj_def_tabla.setNombre(((Lexema)nodo.getIzquierda().getElement()).getLexema());
//                        contador_campos++;
//                    }
                }
                else
                {
                    lista_errores_creacion_tablas.add(new Error("SENTENCIA CREATE", "FALTA IDENTIFICADORES"));
                }
            }
            else if(((Lexema) nodo.getElement()).getLexema().toLowerCase().equals("key") )
            {
                if ( ((Lexema)nodo.getDerecha().getElement()).getLexema().toLowerCase().equals("primary")
                   && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 1
                   &&  ((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 1     )
                {
                    obj_def_tabla.setPrimaria("si");
                }
                else
                {
                    
                    lista_errores_creacion_tablas.add(new Error("SENTENCIA CREATE", "FALTA IDENTIFICADORES"));
                }
            }
            else if(((Lexema) nodo.getElement()).getLexema().toLowerCase().equals("primary") )
            {
                if ( nodo.getDerecha() == null
                   && nodo.getIzquierda() == null )
                {
                    obj_def_tabla.setPrimaria("si");
                }
                else
                {
                    lista_errores_creacion_tablas.add(new Error("SENTENCIA CREATE", "FALTA IDENTIFICADORES"));
                }
            }
            else if(((Lexema) nodo.getElement()).getLexema().toLowerCase().equals("references") )
            {
                if ( (((Lexema)nodo.getIzquierda().getElement()).getLexema().toLowerCase().equals("varchar")
                      || ((Lexema)nodo.getIzquierda().getElement()).getLexema().toLowerCase().equals("double"))
                   && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 4)
                   
                {
                    boolean bandera_repetido =false;
                    ArrayList lista_tablas = new ArrayList();
                    XML obj_xml = new XML("archivos_usados/analisis_lexico/diccionario/tablas.xml");
                    lista_tablas = obj_xml.leerXMLArchivos("tabla", "nombre");

                    for(int i = 0; i< lista_tablas.size(); i++)
                    {
                        System.out.println("TABLA_REFERENCIAS : "+lista_tablas.get(i).toString().toLowerCase()+" | "
                                    +((Lexema)nodo.getDerecha().getElement()).getLexema());
                            
                        if( lista_tablas.get(i).toString().toLowerCase().equals( ((Lexema)nodo.getDerecha().getElement()).getLexema()) )
                        {
                            bandera_repetido = true;
                        }
                    }
                    if(bandera_repetido == true)
                    {
                        System.out.println("-------------->ENTRA AQUI");
                        obj_def_tabla.setTabla_referencia(((Lexema)nodo.getDerecha().getElement()).getLexema().toLowerCase());
                        obj_def_tabla.setForanea("si");
//                        lista_atributos_tabla_crear.add(obj_def_tabla);
                        
                    }
                    else
                    {
                        lista_errores_creacion_tablas.add(new Error("BLOQUE CREATE", "NO SE PUEDE CREAR LA TABLA PORQUE LA TABLA DE REFERENCIA NO EXISTE"));
                    }
                }
                else
                {
                    lista_errores_creacion_tablas.add(new Error("SENTENCIA CREATE", "FALTA IDENTIFICADORES"));
                }

            }
        }
        else  if( ((Lexema)nodo.getElement()).getTipo_lexema() ==  4)
        {
            if ( (nodo.getIzquierda() == null
                  && nodo.getDerecha() == null)
                  || (((Lexema)nodo.getIzquierda().getElement()).getLexema().toLowerCase().equals("{")
                  && ((Lexema)nodo.getDerecha().getElement()).getLexema() == null)
                )
            {
//                System.out.println("**ENTRA AQUI1"+((Lexema)nodo.getIzquierda().getElement()).getLexema()+" | "+((Lexema)nodo.getDerecha().getElement()).getLexema());
//                if(obj_def_tabla.getNombre().equals(""))
//                {
//                    obj_def_tabla = new DefinicionTabla();
////                    obj_def_tabla.setNombre(((Lexema)nodo.getElement()).getLexema().toLowerCase());
//                    obj_def_tabla.setNombre_tabla(nombre_tabla);
//                }
//                else
//                {
//                    if(obj_def_tabla.getForanea().equals(""))
//                    {
//                        obj_def_tabla.setForanea("no");
//                        obj_def_tabla.setTabla_referencia("nulo");
//                    }
//                    if(obj_def_tabla.getPrimaria().equals(""))
//                    {
//                        obj_def_tabla.setPrimaria("no");
//                    }
//                    lista_atributos_tabla_crear.add(obj_def_tabla);
////                    obj_def_tabla.setNombre(((Lexema)nodo.getElement()).getLexema().toLowerCase());
//                    obj_def_tabla = new DefinicionTabla();
//                    obj_def_tabla.setNombre_tabla(nombre_tabla);
//                }
                
            }
            else
            {
                System.out.println("**ENTRA AQUI1"+((Lexema)nodo.getIzquierda().getElement()).getLexema()+" | "+((Lexema)nodo.getDerecha().getElement()).getLexema());


                lista_errores_creacion_tablas.add(new Error("SENTENCIA CREATE", "FALTA IDENTIFICADORES"));
            }
        }
        else  if( ((Lexema)nodo.getElement()).getTipo_lexema() ==  2)
        {
            if ( ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals(",") )
            {
                 if ( (((Lexema)nodo.getIzquierda().getElement()).getLexema().toLowerCase().equals(",")
                  && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 1 )
                  || (((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 1
                  && ((Lexema)nodo.getDerecha().getElement()).getTipo_lexema() == 1)
                )
                {
                }
                else
                {
                     System.out.println("**ENTRA AQUI2"+((Lexema)nodo.getIzquierda().getElement()).getLexema()+" | "+((Lexema)nodo.getDerecha().getElement()).getLexema());


                    lista_errores_creacion_tablas.add(new Error("SENTENCIA CREATE", "FALTA IDENTIFICADORES"));
                }
            }
            else if(((Lexema) nodo.getElement()).getLexema().toLowerCase().equals("{"))
            {
                if ( nodo.getIzquierda() == null
                        &&  nodo.getDerecha() == null )
                {
                }
                else
                {
                    System.out.println("**ENTRA AQUI3"+((Lexema)nodo.getIzquierda().getElement()).getLexema()+" | "+((Lexema)nodo.getDerecha().getElement()).getLexema());


                    lista_errores_creacion_tablas.add(new Error("SENTENCIA CREATE", "FALTA IDENTIFICADORES"));
                }
            }
            else if(((Lexema) nodo.getElement()).getLexema().toLowerCase().equals("}"))
            {
                 if ( (((Lexema)nodo.getIzquierda().getElement()).getLexema().toLowerCase().equals(",")
                  && ((Lexema)nodo.getDerecha().getElement()).getLexema() == null )
                  || (((Lexema)nodo.getIzquierda().getElement()).getTipo_lexema() == 1
                  && ((Lexema)nodo.getDerecha().getElement()).getLexema() == null )
                )
                {
                }
                else
                {
                     System.out.println("**ENTRA AQUI4"+((Lexema)nodo.getIzquierda().getElement()).getLexema()+" | "+((Lexema)nodo.getDerecha().getElement()).getLexema());


                    lista_errores_creacion_tablas.add(new Error("SENTENCIA CREATE", "FALTA IDENTIFICADORES"));
                }
            }
            else
            {
                System.out.println("**ENTRA AQUI5"+((Lexema)nodo.getIzquierda().getElement()).getLexema()+" | "+((Lexema)nodo.getDerecha().getElement()).getLexema());


                lista_errores_creacion_tablas.add(new Error("SENTENCIA CREATE", "FALTA IDENTIFICADORES"));
            }
        }

    }

    public void recorrerSubArbolCreate(BTree nodo)
    {
        if( nodo.getIzquierda()!= null )
        {
            recorrerSubArbolCreate(nodo.getIzquierda());
        }
        if(nodo.getDerecha() != null)
        {
            recorrerSubArbolCreate(nodo.getDerecha());
        }
        if( !(   ((Lexema)nodo.getElement()).getTipo_lexema() == 1
            && ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("create")
            && ((Lexema)nodo.getDerecha().getElement()).getLexema() == null
            && ((Lexema)nodo.getIzquierda().getElement()).getLexema() == null ))
        {
            if(((Lexema)nodo.getElement()).getLexema() != null)
            {
                lista_errores_creacion_tablas.add(new Error("BLOQUE CREATE", "NO COMIENZA CON LA PALABRA CREATE"));
            }

        }
    }

    public void recorrerSubArbolTable(BTree nodo)
    {
        if( nodo.getIzquierda()!= null )
        {
            recorrerSubArbolTable(nodo.getIzquierda());
        }
        if(nodo.getDerecha() != null)
        {
            recorrerSubArbolTable(nodo.getDerecha());
        }
        if(((Lexema)nodo.getElement()).getTipo_lexema() == 4 )
        {
            if( nodo.getDerecha() == null && nodo.getIzquierda() == null)
            {
                boolean bandera_repetido =false;
                ArrayList lista_tablas = new ArrayList();
                XML obj_xml = new XML("archivos_usados/analisis_lexico/diccionario/tablas.xml");
                lista_tablas = obj_xml.leerXMLArchivos("tabla", "nombre");

                for(int i = 0; i< lista_tablas.size(); i++)
                {System.out.println("TABLA_REPETIDA : "+lista_tablas.get(i).toString().toLowerCase()+"|"+((Lexema)nodo.getElement()).getLexema().toLowerCase());
                        
                    if( lista_tablas.get(i).toString().toLowerCase().equals( ((Lexema)nodo.getElement()).getLexema().toLowerCase()) )
                    {
                        System.out.println("TABLA_REPETIDA : "+lista_tablas.get(i).toString().toLowerCase()+"|"+((Lexema)nodo.getElement()).getLexema().toLowerCase());
                        bandera_repetido = true;
                    }
                }
                if(bandera_repetido == true)
                {
                    lista_errores_creacion_tablas.add(new Error("BLOQUE CREATE", "NO SE PUEDE CREAR LA TABLA PORQ ESTA YA EXISTEs"));
                }
                else
                {
                    nombre_tabla = ((Lexema)nodo.getElement()).getLexema().toLowerCase();
                }
            }
            else
            {
                lista_errores_creacion_tablas.add(new Error("BLOQUE CREATE", "SOLO DEBE CONTENER UN IDENTIFICADOR DE TABLA"));
            }
        }
        else if( ((Lexema) nodo.getElement()).getTipo_lexema() == 1
                 && ((Lexema)nodo.getElement()).getLexema().toLowerCase().equals("table")
            )
        {
            if( !( ((Lexema)nodo.getDerecha().getElement()).getLexema() == null
                    && ((Lexema)nodo.getIzquierda().getElement()).getLexema() != null ))
            {
                lista_errores_creacion_tablas.add(new Error("BLOQUE CREATE", "NO COMIENZA CON LA PALABRA CREATE"));
            }

        }
        else if( ((Lexema)nodo.getElement()).getLexema() == null)
        {

        }
        else
        {
            lista_errores_creacion_tablas.add(new Error("BLOQUE CREATE", "LA SENTENCIA CREATE ESTA MAL"));
        }
    }

    public void imprimirMatriz(ObjetoQuery[][] matriz)
    {
        System.out.println("*********** SELECCION **************");
        for(int i = 0; i<matriz.length; i++)
        {
            for(int j = 0; j<matriz[0].length; j++)
            {
                System.out.print(matriz[i][j].getObjeto()+" | ");
//                System.out.print(matriz[i][j].getTabla()+"."+matriz[i][j].getColumna()+" | ");
            }
            System.out.println("");
        }
    }

    
   

    public int buscarPuntoCadena(String cadena)
    {
        int numero_repitencia_punto = 0;
        for(int i = 0; i<cadena.length(); i++)
        {
            if(cadena.charAt(i) == '.')
            {
                numero_repitencia_punto++;
            }
        }
        return numero_repitencia_punto;
    }


   
    /**
     * @return the lista_lexemas
     */
    public ArrayList getLista_lexemas() {
        return lista_lexemas;
    }

    /**
     * @param lista_lexemas the lista_lexemas to set
     */
    public void setLista_lexemas(ArrayList lista_lexemas) {
        this.lista_lexemas = lista_lexemas;
    }

}
